import tkinter as tk
from tkinter import ttk, messagebox, simpledialog, filedialog
import pymysql
import csv
from datetime import datetime

# 数据库配置
DB_CONFIG = {
    'host': 'localhost',
    'user': 'root',
    'password': '041128clxK',
    'database': '课设',
    'port': 3306
}

# ========== 数据库操作 ==========
class Database:
    @staticmethod
    def connect():
        try:
            return pymysql.connect(
                host=DB_CONFIG['host'],
                user=DB_CONFIG['user'],
                password=DB_CONFIG['password'],
                database=DB_CONFIG['database'],
                port=DB_CONFIG['port'],
                cursorclass=pymysql.cursors.DictCursor
            )
        except pymysql.Error as e:
            messagebox.showerror("数据库错误", f"连接失败：{str(e)}")
            return None
    
    @staticmethod
    def execute_query(query, params=None):
        conn = Database.connect()
        if not conn:
            return None
        try:
            with conn.cursor() as cursor:
                cursor.execute(query, params or ())
                conn.commit()
                return cursor.rowcount
        except pymysql.Error as e:
            messagebox.showerror("数据库错误", f"操作失败：{str(e)}")
            conn.rollback()
        finally:
            if conn and conn.open:
                conn.close()
    
    @staticmethod
    def fetch_one(query, params=None):
        conn = Database.connect()
        if not conn:
            return None
        try:
            with conn.cursor() as cursor:
                cursor.execute(query, params or ())
                return cursor.fetchone()
        except pymysql.Error as e:
            messagebox.showerror("数据库错误", f"查询失败：{str(e)}")
        finally:
            if conn and conn.open:
                conn.close()
    
    @staticmethod
    def fetch_all(query, params=None):
        conn = Database.connect()
        if not conn:
            return None
        try:
            with conn.cursor() as cursor:
                cursor.execute(query, params or ())
                return cursor.fetchall()
        finally:
            if conn and conn.open:
                conn.close()

# ========== 客户管理界面 ==========
class CustomerManagement:
    def __init__(self, root, username):
        self.root = root
        self.root.title("管理员 - 客户管理")
        self.root.geometry("900x600")
        self.root.configure(bg="#E6F7FF")
        self.username = username
        
        # 界面配置
        self.btn_bg = "#66CCFF"
        self.btn_fg = "white"
        self.font = ("SimHei", 10)
        self.title_font = ("SimHei", 12, "bold")
        
        # 添加调试信息
        print(f"CustomerManagement 初始化完成，用户: {username}")
        
        try:
            self.create_widgets()
            # 延迟加载数据，确保窗口完全创建
            self.root.after(100, self.load_customers)
        except Exception as e:
            messagebox.showerror("初始化错误", f"客户管理界面初始化失败：{str(e)}")
            print(f"CustomerManagement 初始化错误: {e}")

    def create_widgets(self):
        """创建客户管理界面组件"""
        # 标题
        tk.Label(
            self.root, 
            text="客户管理系统", 
            font=("SimHei", 16, "bold"),
            bg="#E6F7FF",
            fg="#333333"
        ).pack(pady=10)
        
        # 功能按钮栏
        btn_frame = tk.Frame(self.root, bg="#E6F7FF")
        btn_frame.pack(fill=tk.X, padx=20, pady=10)
        
        tk.Button(
            btn_frame, 
            text="添加客户", 
            command=self.add_customer,
            bg=self.btn_bg,
            fg=self.btn_fg,
            font=self.font,
            padx=10,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).pack(side=tk.LEFT, padx=5)
        
        tk.Button(
            btn_frame, 
            text="修改客户", 
            command=self.modify_customer,
            bg=self.btn_bg,
            fg=self.btn_fg,
            font=self.font,
            padx=10,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).pack(side=tk.LEFT, padx=5)
        
        tk.Button(
            btn_frame, 
            text="删除客户", 
            command=self.delete_customer,
            bg=self.btn_bg,
            fg=self.btn_fg,
            font=self.font,
            padx=10,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).pack(side=tk.LEFT, padx=5)
        
        tk.Button(
            btn_frame, 
            text="导出CSV", 
            command=self.export_to_csv,
            bg=self.btn_bg,
            fg=self.btn_fg,
            font=self.font,
            padx=10,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).pack(side=tk.LEFT, padx=5)
        
        # 搜索栏
        search_frame = tk.Frame(self.root, bg="#E6F7FF")
        search_frame.pack(fill=tk.X, padx=20, pady=5)
        
        tk.Label(
            search_frame, 
            text="搜索客户:", 
            font=self.font,
            bg="#E6F7FF",
            fg="#333333"
        ).pack(side=tk.LEFT, padx=5)
        
        # 修复StringVar绑定问题 - 明确指定master
        self.search_var = tk.StringVar(master=self.root)
        self.search_entry = tk.Entry(
            search_frame, 
            textvariable=self.search_var,
            width=30,
            font=self.font,
            bd=1,
            relief="solid"
        )
        self.search_entry.pack(side=tk.LEFT, padx=5, fill=tk.X, expand=True)
        
        # 绑定回车键到搜索功能
        self.search_entry.bind('<Return>', lambda event: self.debug_search_customers())
        
        tk.Button(
            search_frame, 
            text="搜索", 
            command=lambda: self.debug_search_customers(),
            bg=self.btn_bg,
            fg=self.btn_fg,
            font=self.font,
            padx=5,
            pady=2,
            relief="flat",
            cursor="hand2"
        ).pack(side=tk.LEFT, padx=5)
        
        tk.Button(
            search_frame, 
            text="重置", 
            command=self.load_customers,
            bg="#CCCCCC",
            fg="black",
            font=self.font,
            padx=5,
            pady=2,
            relief="flat",
            cursor="hand2"
        ).pack(side=tk.LEFT, padx=5)
        
        # 客户列表
        self.customer_tree = ttk.Treeview(
            self.root,
            columns=("customerID", "customerName", "PID", "telephone", "address"),
            show="headings",
            height=15
        )
        
        self.customer_tree.heading("customerID", text="客户编号")
        self.customer_tree.heading("customerName", text="客户姓名")
        self.customer_tree.heading("PID", text="身份证号")
        self.customer_tree.heading("telephone", text="联系电话")
        self.customer_tree.heading("address", text="联系地址")
        
        self.customer_tree.column("customerID", width=80, anchor=tk.CENTER)
        self.customer_tree.column("customerName", width=100, anchor=tk.CENTER)
        self.customer_tree.column("PID", width=180, anchor=tk.CENTER)
        self.customer_tree.column("telephone", width=120, anchor=tk.CENTER)
        self.customer_tree.column("address", width=300, anchor=tk.CENTER)
        
        self.customer_tree.pack(fill=tk.BOTH, expand=True, padx=20, pady=10)
        self.customer_tree.bind("<Double-1>", lambda e: self.show_customer_details())
        
        # 状态栏
        self.status_var = tk.StringVar()
        self.status_var.set(f"当前用户: {self.username} | 客户数量: 0")
        tk.Label(
            self.root, 
            textvariable=self.status_var, 
            font=self.font,
            bg="#E6F7FF",
            fg="#333333"
        ).pack(side=tk.BOTTOM, fill=tk.X, padx=20, pady=5)

    def load_customers(self):
        """加载所有客户信息"""
        try:
            for item in self.customer_tree.get_children():
                self.customer_tree.delete(item)
            
            query = "SELECT customerID, customerName, PID, telephone, address FROM userinfo"
            customers = Database.fetch_all(query)
            
            if customers:
                for customer in customers:
                    self.customer_tree.insert(
                        "", 
                        tk.END,
                        values=(
                            customer["customerID"],
                            customer["customerName"],
                            customer["PID"],
                            customer["telephone"],
                            customer["address"] or "未填写"
                        )
                    )
                self.status_var.set(f"当前用户: {self.username} | 客户数量: {len(customers)}")
            else:
                self.status_var.set(f"当前用户: {self.username} | 客户数量: 0")
                
        except Exception as e:
            # 添加错误处理
            messagebox.showerror("加载错误", f"加载客户数据时发生错误：{str(e)}")
            self.status_var.set(f"当前用户: {self.username} | 数据加载失败")

    def debug_search_customers(self):
        """调试版本的搜索客户信息"""
        print("搜索按钮被点击")
        try:
            keyword = self.search_var.get().strip()
            print(f"搜索关键词: '{keyword}'")
            
            if not keyword:
                print("关键词为空，重新加载所有客户")
                self.load_customers()
                return
            
            print("开始执行搜索...")
            self.search_customers()
            print("搜索执行完成")
            
        except Exception as e:
            print(f"搜索过程中发生错误: {e}")
            messagebox.showerror("搜索错误", f"搜索过程中发生错误：{str(e)}")

    def search_customers(self):
        """搜索客户信息"""
        try:
            keyword = self.search_var.get().strip()
            if not keyword:
                self.load_customers()
                return
            
            # 清空当前列表
            for item in self.customer_tree.get_children():
                self.customer_tree.delete(item)
            
            # 执行搜索查询
            query = """
            SELECT customerID, customerName, PID, telephone, address 
            FROM userinfo 
            WHERE customerName LIKE %s OR PID LIKE %s OR telephone LIKE %s OR address LIKE %s
            """
            customers = Database.fetch_all(query, (f"%{keyword}%", f"%{keyword}%", f"%{keyword}%", f"%{keyword}%"))
            
            if customers:
                for customer in customers:
                    self.customer_tree.insert(
                        "", 
                        tk.END,
                        values=(
                            customer["customerID"],
                            customer["customerName"],
                            customer["PID"],
                            customer["telephone"],
                            customer["address"] or "未填写"
                        )
                    )
                self.status_var.set(f"搜索结果: {len(customers)} 条")
            else:
                self.status_var.set("搜索结果: 未找到匹配的客户")
                
        except Exception as e:
            # 添加错误处理
            messagebox.showerror("搜索错误", f"搜索过程中发生错误：{str(e)}")
            self.status_var.set("搜索失败")
            # 如果搜索失败，重新加载所有客户
            self.load_customers()

    def add_customer(self):
        """添加新客户"""
        dialog = tk.Toplevel(self.root)
        dialog.title("添加客户")
        dialog.geometry("400x350")
        dialog.configure(bg="#E6F7FF")
        dialog.transient(self.root)
        dialog.grab_set()
        
        # 输入框变量 - 明确指定master为dialog
        name_var = tk.StringVar(master=dialog)
        pid_var = tk.StringVar(master=dialog)
        phone_var = tk.StringVar(master=dialog)
        address_var = tk.StringVar(master=dialog)
        
        # 表单布局
        tk.Label(
            dialog, 
            text="客户姓名:", 
            font=self.font,
            bg="#E6F7FF",
            fg="#333333"
        ).place(relx=0.1, rely=0.1, anchor=tk.W)
        tk.Entry(dialog, textvariable=name_var, width=30).place(relx=0.5, rely=0.1, anchor=tk.CENTER)
        
        tk.Label(
            dialog, 
            text="身份证号:", 
            font=self.font,
            bg="#E6F7FF",
            fg="#333333"
        ).place(relx=0.1, rely=0.2, anchor=tk.W)
        tk.Entry(dialog, textvariable=pid_var, width=30).place(relx=0.5, rely=0.2, anchor=tk.CENTER)
        
        tk.Label(
            dialog, 
            text="联系电话:", 
            font=self.font,
            bg="#E6F7FF",
            fg="#333333"
        ).place(relx=0.1, rely=0.3, anchor=tk.W)
        tk.Entry(dialog, textvariable=phone_var, width=30).place(relx=0.5, rely=0.3, anchor=tk.CENTER)
        
        tk.Label(
            dialog, 
            text="联系地址:", 
            font=self.font,
            bg="#E6F7FF",
            fg="#333333"
        ).place(relx=0.1, rely=0.4, anchor=tk.W)
        tk.Entry(dialog, textvariable=address_var, width=30).place(relx=0.5, rely=0.4, anchor=tk.CENTER)
        
        # 验证函数
        def validate_and_save():
            name = name_var.get().strip()
            pid = pid_var.get().strip()
            phone = phone_var.get().strip()
            address = address_var.get().strip()
            
            if not name or not pid or not phone:
                messagebox.showerror("错误", "姓名、身份证号和电话不能为空！")
                return
            
            if len(pid) not in (15, 18):
                messagebox.showerror("错误", "身份证号应为15或18位！")
                return
            
            if len(phone) != 11 or not phone.isdigit():
                messagebox.showerror("错误", "请输入有效的11位电话号码！")
                return
            
            # 检查身份证号是否已存在
            exists = Database.fetch_one("SELECT PID FROM userinfo WHERE PID = %s", (pid,))
            if exists:
                messagebox.showerror("错误", "该身份证号已注册！")
                return
            
            # 保存到数据库
            result = Database.execute_query(
                "INSERT INTO userinfo (customerName, PID, telephone, address) VALUES (%s, %s, %s, %s)",
                (name, pid, phone, address)
            )
            
            if result:
                messagebox.showinfo("成功", "客户添加成功！")
                dialog.destroy()
                self.load_customers()
            else:
                messagebox.showerror("错误", "客户添加失败！")
        
        # 按钮
        tk.Button(
            dialog, 
            text="保存", 
            command=validate_and_save,
            bg=self.btn_bg,
            fg=self.btn_fg,
            font=self.font,
            padx=10,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).place(relx=0.4, rely=0.7, anchor=tk.CENTER)
        
        tk.Button(
            dialog, 
            text="取消", 
            command=dialog.destroy,
            bg="#CCCCCC",
            fg="black",
            font=self.font,
            padx=10,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).place(relx=0.6, rely=0.7, anchor=tk.CENTER)

    def get_selected_customer(self):
        """获取选中的客户ID"""
        selected_items = self.customer_tree.selection()
        if not selected_items:
            messagebox.showwarning("警告", "请先选择一个客户！")
            return None
        
        item = self.customer_tree.item(selected_items[0])
        return item["values"][0]  # 返回客户ID

    def show_customer_details(self):
        """显示客户详情"""
        customer_id = self.get_selected_customer()
        if not customer_id:
            return
        
        # 获取客户信息
        customer = Database.fetch_one(
            "SELECT customerID, customerName, PID, telephone, address FROM userinfo WHERE customerID = %s",
            (customer_id,)
        )
        
        if customer:
            # 创建详情对话框
            dialog = tk.Toplevel(self.root)
            dialog.title(f"客户详情 - {customer['customerName']}")
            dialog.geometry("400x300")
            dialog.configure(bg="#E6F7FF")
            
            tk.Label(
                dialog, 
                text="客户编号:", 
                font=self.font,
                bg="#E6F7FF",
                fg="#333333"
            ).place(relx=0.1, rely=0.1, anchor=tk.W)
            tk.Label(dialog, text=customer["customerID"], font=self.font).place(relx=0.5, rely=0.1, anchor=tk.CENTER)
            
            tk.Label(
                dialog, 
                text="客户姓名:", 
                font=self.font,
                bg="#E6F7FF",
                fg="#333333"
            ).place(relx=0.1, rely=0.2, anchor=tk.W)
            tk.Label(dialog, text=customer["customerName"], font=self.font).place(relx=0.5, rely=0.2, anchor=tk.CENTER)
            
            tk.Label(
                dialog, 
                text="身份证号:", 
                font=self.font,
                bg="#E6F7FF",
                fg="#333333"
            ).place(relx=0.1, rely=0.3, anchor=tk.W)
            tk.Label(dialog, text=customer["PID"], font=self.font).place(relx=0.5, rely=0.3, anchor=tk.CENTER)
            
            tk.Label(
                dialog, 
                text="联系电话:", 
                font=self.font,
                bg="#E6F7FF",
                fg="#333333"
            ).place(relx=0.1, rely=0.4, anchor=tk.W)
            tk.Label(dialog, text=customer["telephone"], font=self.font).place(relx=0.5, rely=0.4, anchor=tk.CENTER)
            
            tk.Label(
                dialog, 
                text="联系地址:", 
                font=self.font,
                bg="#E6F7FF",
                fg="#333333"
            ).place(relx=0.1, rely=0.5, anchor=tk.W)
            tk.Label(dialog, text=customer["address"] or "未填写", font=self.font).place(relx=0.5, rely=0.5, anchor=tk.CENTER)
            
            # 获取客户的银行卡信息
            cards = Database.fetch_all(
                "SELECT cardid, balance FROM cardinfo WHERE customerid = %s",
                (customer_id,)
            )
            
            if cards:
                tk.Label(
                    dialog, 
                    text="银行卡信息:", 
                    font=self.font,
                    bg="#E6F7FF",
                    fg="#333333"
                ).place(relx=0.1, rely=0.6, anchor=tk.W)
                
                card_info = "\n".join([f"卡号: {card['cardid']}, 余额: {float(card['balance']):.2f}" for card in cards])
                tk.Label(
                    dialog, 
                    text=card_info, 
                    font=self.font,
                    bg="#E6F7FF",
                    fg="#333333",
                    justify=tk.LEFT
                ).place(relx=0.1, rely=0.65, anchor=tk.W)
            
            tk.Button(
                dialog, 
                text="关闭", 
                command=dialog.destroy,
                bg="#CCCCCC",
                fg="black",
                font=self.font,
                padx=10,
                pady=5,
                relief="flat",
                cursor="hand2"
            ).place(relx=0.5, rely=0.9, anchor=tk.CENTER)

    def modify_customer(self):
        """修改客户信息"""
        customer_id = self.get_selected_customer()
        if not customer_id:
            return
        
        # 获取当前客户信息
        customer = Database.fetch_one(
            "SELECT customerName, PID, telephone, address FROM userinfo WHERE customerID = %s",
            (customer_id,)
        )
        
        if not customer:
            messagebox.showerror("错误", "获取客户信息失败！")
            return
        
        # 创建修改对话框
        dialog = tk.Toplevel(self.root)
        dialog.title("修改客户")
        dialog.geometry("400x350")
        dialog.configure(bg="#E6F7FF")
        dialog.transient(self.root)
        dialog.grab_set()
        
        # 输入框变量 - 明确指定master为dialog
        name_var = tk.StringVar(master=dialog, value=customer["customerName"])
        pid_var = tk.StringVar(master=dialog, value=customer["PID"])
        phone_var = tk.StringVar(master=dialog, value=customer["telephone"])
        address_var = tk.StringVar(master=dialog, value=customer["address"] or "")
        
        # 表单布局
        tk.Label(dialog, text="客户姓名:", font=self.font, bg="#E6F7FF").place(relx=0.1, rely=0.1, anchor=tk.W)
        tk.Entry(dialog, textvariable=name_var, width=30).place(relx=0.5, rely=0.1, anchor=tk.CENTER)
        
        tk.Label(dialog, text="身份证号:", font=self.font, bg="#E6F7FF").place(relx=0.1, rely=0.2, anchor=tk.W)
        tk.Entry(dialog, textvariable=pid_var, width=30, state="readonly").place(relx=0.5, rely=0.2, anchor=tk.CENTER)
        
        tk.Label(dialog, text="联系电话:", font=self.font, bg="#E6F7FF").place(relx=0.1, rely=0.3, anchor=tk.W)
        tk.Entry(dialog, textvariable=phone_var, width=30).place(relx=0.5, rely=0.3, anchor=tk.CENTER)
        
        tk.Label(dialog, text="联系地址:", font=self.font, bg="#E6F7FF").place(relx=0.1, rely=0.4, anchor=tk.W)
        tk.Entry(dialog, textvariable=address_var, width=30).place(relx=0.5, rely=0.4, anchor=tk.CENTER)
        
        def validate_and_save():
            name = name_var.get().strip()
            phone = phone_var.get().strip()
            address = address_var.get().strip()
            
            if not name or not phone:
                messagebox.showerror("错误", "姓名和电话不能为空！")
                return
            
            if len(phone) != 11 or not phone.isdigit():
                messagebox.showerror("错误", "请输入有效的11位电话号码！")
                return
            
            # 保存到数据库
            result = Database.execute_query(
                "UPDATE userinfo SET customerName = %s, telephone = %s, address = %s WHERE customerID = %s",
                (name, phone, address, customer_id)
            )
            
            if result:
                messagebox.showinfo("成功", "客户信息修改成功！")
                dialog.destroy()
                self.load_customers()
            else:
                messagebox.showerror("错误", "客户信息修改失败！")
        
        tk.Button(
            dialog, 
            text="保存", 
            command=validate_and_save,
            bg=self.btn_bg,
            fg=self.btn_fg,
            font=self.font,
            padx=10,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).place(relx=0.4, rely=0.7, anchor=tk.CENTER)
        
        tk.Button(
            dialog, 
            text="取消", 
            command=dialog.destroy,
            bg="#CCCCCC",
            fg="black",
            font=self.font,
            padx=10,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).place(relx=0.6, rely=0.7, anchor=tk.CENTER)

    def delete_customer(self):
        """删除客户"""
        customer_id = self.get_selected_customer()
        if not customer_id:
            return
        
        # 确认删除
        if not messagebox.askyesno("确认", "确定要删除该客户吗？此操作不可恢复！"):
            return
        
        # 检查是否有关联的银行卡
        cards = Database.fetch_all("SELECT cardid FROM cardinfo WHERE customerid = %s", (customer_id,))
        if cards:
            messagebox.showerror("错误", "该客户有关联的银行卡，不能直接删除！")
            return
        
        # 执行删除
        result = Database.execute_query("DELETE FROM userinfo WHERE customerID = %s", (customer_id,))
        
        if result:
            messagebox.showinfo("成功", "客户删除成功！")
            self.load_customers()
        else:
            messagebox.showerror("错误", "客户删除失败！")

    def export_to_csv(self):
        """导出客户数据到 CSV"""
        customers = Database.fetch_all("SELECT customerID, customerName, PID, telephone, address FROM userinfo")
        if not customers:
            messagebox.showinfo("提示", "没有客户数据可导出！")
            return
        
        # 选择保存路径
        file_path = filedialog.asksaveasfilename(
            defaultextension=".csv",
            filetypes=[("CSV文件", "*.csv"), ("所有文件", "*.*")],
            title="保存CSV文件"
        )
        
        if not file_path:
            return
        
        # 写入 CSV 文件
        try:
            with open(file_path, 'w', newline='', encoding='utf-8-sig') as f:
                writer = csv.writer(f)
                writer.writerow(["客户编号", "客户姓名", "身份证号", "联系电话", "联系地址"])
                for customer in customers:
                    writer.writerow([
                        customer["customerID"],
                        customer["customerName"],
                        customer["PID"],
                        customer["telephone"],
                        customer["address"] or ""
                    ])
            
            messagebox.showinfo("成功", f"客户数据已成功导出到\n{file_path}")
        except Exception as e:
            messagebox.showerror("错误", f"导出失败：{str(e)}")

# ========== 银行卡管理界面 ==========
class BankCardManagement:
    def __init__(self, root, username):
        self.root = root
        self.root.title("管理员 - 银行卡管理")
        self.root.geometry("900x600")
        self.root.configure(bg="#E6F7FF")
        self.username = username

        # 界面配置
        self.btn_bg = "#66CCFF"
        self.btn_fg = "white"
        self.font = ("SimHei", 10)
        self.title_font = ("SimHei", 12, "bold")

        self.create_widgets()
        self.load_bank_cards()

    def create_widgets(self):
        """创建银行卡管理界面组件"""
        # 标题
        tk.Label(
            self.root, 
            text="银行卡管理系统", 
            font=("SimHei", 16, "bold"),
            bg="#E6F7FF",
            fg="#333333"
        ).pack(pady=10)

        # 功能按钮栏
        btn_frame = tk.Frame(self.root, bg="#E6F7FF")
        btn_frame.pack(fill=tk.X, padx=20, pady=10)

        tk.Button(
            btn_frame, 
            text="添加银行卡", 
            command=self.add_bank_card,
            bg=self.btn_bg,
            fg=self.btn_fg,
            font=self.font,
            padx=10,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).pack(side=tk.LEFT, padx=5)

        tk.Button(
            btn_frame, 
            text="挂失/解挂", 
            command=self.handle_report_loss,
            bg=self.btn_bg,
            fg=self.btn_fg,
            font=self.font,
            padx=10,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).pack(side=tk.LEFT, padx=5)

        tk.Button(
            btn_frame, 
            text="修改密码", 
            command=self.handle_change_password,
            bg=self.btn_bg,
            fg=self.btn_fg,
            font=self.font,
            padx=10,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).pack(side=tk.LEFT, padx=5)

        tk.Button(
            btn_frame, 
            text="修改银行卡信息", 
            command=self.modify_bank_card,
            bg=self.btn_bg,
            fg=self.btn_fg,
            font=self.font,
            padx=10,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).pack(side=tk.LEFT, padx=5)

        tk.Button(
            btn_frame, 
            text="删除银行卡", 
            command=self.delete_bank_card,
            bg=self.btn_bg,
            fg=self.btn_fg,
            font=self.font,
            padx=10,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).pack(side=tk.LEFT, padx=5)

        tk.Button(
            btn_frame, 
            text="导出CSV", 
            command=self.export_to_csv,
            bg=self.btn_bg,
            fg=self.btn_fg,
            font=self.font,
            padx=10,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).pack(side=tk.LEFT, padx=5)

        # 搜索栏
        search_frame = tk.Frame(self.root, bg="#E6F7FF")
        search_frame.pack(fill=tk.X, padx=20, pady=5)

        tk.Label(
            search_frame, 
            text="搜索银行卡:", 
            font=self.font,
            bg="#E6F7FF",
            fg="#333333"
        ).pack(side=tk.LEFT, padx=5)

        self.search_var = tk.StringVar()
        tk.Entry(
            search_frame, 
            textvariable=self.search_var,
            width=30,
            font=self.font,
            bd=1,
            relief="solid"
        ).pack(side=tk.LEFT, padx=5, fill=tk.X, expand=True)

        tk.Button(
            search_frame, 
            text="搜索", 
            command=self.search_bank_cards,
            bg=self.btn_bg,
            fg=self.btn_fg,
            font=self.font,
            padx=5,
            pady=2,
            relief="flat",
            cursor="hand2"
        ).pack(side=tk.LEFT, padx=5)

        tk.Button(
            search_frame, 
            text="重置", 
            command=self.load_bank_cards,
            bg="#CCCCCC",
            fg="black",
            font=self.font,
            padx=5,
            pady=2,
            relief="flat",
            cursor="hand2"
        ).pack(side=tk.LEFT, padx=5)

        # 银行卡列表
        self.bank_card_tree = ttk.Treeview(
            self.root,
            columns=("cardID", "customerID", "curID", "savingName", "openDate", "openAmount", "balance", "isLost"),
            show="headings",
            height=15
        )

        self.bank_card_tree.heading("cardID", text="卡号")
        self.bank_card_tree.heading("customerID", text="客户编号")
        self.bank_card_tree.heading("curID", text="币种")
        self.bank_card_tree.heading("savingName", text="存款名称")
        self.bank_card_tree.heading("openDate", text="开户日期")
        self.bank_card_tree.heading("openAmount", text="开户金额")
        self.bank_card_tree.heading("balance", text="余额")
        self.bank_card_tree.heading("isLost", text="是否挂失")

        self.bank_card_tree.column("cardID", width=150, anchor=tk.CENTER)
        self.bank_card_tree.column("customerID", width=100, anchor=tk.CENTER)
        self.bank_card_tree.column("curID", width=100, anchor=tk.CENTER)
        self.bank_card_tree.column("savingName", width=150, anchor=tk.CENTER)
        self.bank_card_tree.column("openDate", width=120, anchor=tk.CENTER)
        self.bank_card_tree.column("openAmount", width=100, anchor=tk.CENTER)
        self.bank_card_tree.column("balance", width=100, anchor=tk.CENTER)
        self.bank_card_tree.column("isLost", width=80, anchor=tk.CENTER)

        self.bank_card_tree.pack(fill=tk.BOTH, expand=True, padx=20, pady=10)
        self.bank_card_tree.bind("<Double-1>", lambda e: self.show_bank_card_details())

        # 状态栏
        self.status_var = tk.StringVar()
        self.status_var.set(f"当前用户: {self.username} | 银行卡数量: 0")
        tk.Label(
            self.root, 
            textvariable=self.status_var, 
            font=self.font,
            bg="#E6F7FF",
            fg="#333333"
        ).pack(side=tk.BOTTOM, fill=tk.X, padx=20, pady=5)

    def load_bank_cards(self):
        """加载所有银行卡信息"""
        for item in self.bank_card_tree.get_children():
            self.bank_card_tree.delete(item)

        query = """
        SELECT cardinfo.cardID, cardinfo.customerID, cardinfo.curID, deposit.savingName, 
               cardinfo.openDate, cardinfo.openMoney AS openAmount, cardinfo.balance, 
               cardinfo.IsReportLoss AS isLost
        FROM cardinfo
        JOIN deposit ON cardinfo.savingID = deposit.savingID
        """
        bank_cards = Database.fetch_all(query)

        if bank_cards:
            for card in bank_cards:
               
                loss_status = str(card["isLost"]).strip()
                if loss_status == '是' or loss_status == '1' or loss_status.upper() == 'TRUE':
                    display_status = '是'
                else:
                    display_status = '否'
                
                self.bank_card_tree.insert(
                    "", 
                    tk.END,
                    values=(
                        card["cardID"],
                        card["customerID"],
                        card["curID"],
                        card["savingName"],
                        card["openDate"].strftime("%Y-%m-%d %H:%M:%S"),
                        card["openAmount"],
                        card["balance"],
                        display_status
                    )
                )
            self.status_var.set(f"当前用户: {self.username} | 银行卡数量: {len(bank_cards)}")
        else:
            self.status_var.set(f"当前用户: {self.username} | 银行卡数量: 0")

    def search_bank_cards(self):
        """搜索银行卡信息"""
        keyword = self.search_var.get().strip()
        if not keyword:
            self.load_bank_cards()
            return

        for item in self.bank_card_tree.get_children():
            self.bank_card_tree.delete(item)

        query = """
        SELECT cardinfo.cardID, cardinfo.customerID, cardinfo.curID, deposit.savingName, 
               cardinfo.openDate, cardinfo.openMoney AS openAmount, cardinfo.balance, 
               cardinfo.IsReportLoss AS isLost
        FROM cardinfo
        JOIN deposit ON cardinfo.savingID = deposit.savingID
        WHERE cardinfo.cardID LIKE %s OR cardinfo.customerID LIKE %s OR deposit.savingName LIKE %s
        """
        bank_cards = Database.fetch_all(query, (f"%{keyword}%", f"%{keyword}%", f"%{keyword}%"))

        if bank_cards:
            for card in bank_cards:
            
                loss_status = str(card["isLost"]).strip()
                if loss_status == '是' or loss_status == '1' or loss_status.upper() == 'TRUE':
                    display_status = '是'
                else:
                    display_status = '否'
                
                self.bank_card_tree.insert(
                    "", 
                    tk.END,
                    values=(
                        card["cardID"],
                        card["customerID"],
                        card["curID"],
                        card["savingName"],
                        card["openDate"].strftime("%Y-%m-%d %H:%M:%S"),
                        card["openAmount"],
                        card["balance"],
                        display_status
                    )
                )
            self.status_var.set(f"搜索结果: {len(bank_cards)} 条")
        else:
            self.status_var.set("搜索结果: 未找到匹配的银行卡")

    def add_bank_card(self):
        """添加新银行卡"""
        dialog = tk.Toplevel(self.root)
        dialog.title("添加银行卡")
        dialog.geometry("400x450")
        dialog.configure(bg="#E6F7FF")
        dialog.transient(self.root)
        dialog.grab_set()

        card_id_var = tk.StringVar(master=dialog)
        customer_id_var = tk.StringVar(master=dialog)
        cur_id_var = tk.StringVar(master=dialog)
        saving_name_var = tk.StringVar(master=dialog)
        open_date_var = tk.StringVar(master=dialog, value=datetime.now().strftime("%Y-%m-%d"))
        open_amount_var = tk.StringVar(master=dialog)
        balance_var = tk.StringVar(master=dialog)
        password_var = tk.StringVar(master=dialog)
        is_lost_var = tk.StringVar(master=dialog, value="否")

        tk.Label(dialog, text="卡号:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.1, anchor=tk.W)
        tk.Entry(dialog, textvariable=card_id_var, width=30).place(relx=0.5, rely=0.1, anchor=tk.CENTER)

        tk.Label(dialog, text="客户编号:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.2, anchor=tk.W)
        tk.Entry(dialog, textvariable=customer_id_var, width=30).place(relx=0.5, rely=0.2, anchor=tk.CENTER)

        tk.Label(dialog, text="币种:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.3, anchor=tk.W)
        tk.Entry(dialog, textvariable=cur_id_var, width=30).place(relx=0.5, rely=0.3, anchor=tk.CENTER)

        tk.Label(dialog, text="存款名称:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.4, anchor=tk.W)
        tk.Entry(dialog, textvariable=saving_name_var, width=30).place(relx=0.5, rely=0.4, anchor=tk.CENTER)

        tk.Label(dialog, text="开户日期:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.5, anchor=tk.W)
        tk.Entry(dialog, textvariable=open_date_var, width=30).place(relx=0.5, rely=0.5, anchor=tk.CENTER)

        tk.Label(dialog, text="开户金额:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.6, anchor=tk.W)
        tk.Entry(dialog, textvariable=open_amount_var, width=30).place(relx=0.5, rely=0.6, anchor=tk.CENTER)

        tk.Label(dialog, text="余额:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.7, anchor=tk.W)
        tk.Entry(dialog, textvariable=balance_var, width=30).place(relx=0.5, rely=0.7, anchor=tk.CENTER)

        tk.Label(dialog, text="密码:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.8, anchor=tk.W)
        tk.Entry(dialog, textvariable=password_var, width=30).place(relx=0.5, rely=0.8, anchor=tk.CENTER)

        tk.Label(dialog, text="是否挂失:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.9, anchor=tk.W)
        tk.Entry(dialog, textvariable=is_lost_var, width=30).place(relx=0.5, rely=0.9, anchor=tk.CENTER)

        def validate_and_save():
            card_id = card_id_var.get().strip()
            customer_id = customer_id_var.get().strip()
            cur_id = cur_id_var.get().strip()
            saving_name = saving_name_var.get().strip()
            open_date = open_date_var.get().strip()
            open_amount = open_amount_var.get().strip()
            balance = balance_var.get().strip()
            password = password_var.get().strip()
            is_lost = is_lost_var.get().strip()

            if not card_id or not customer_id or not cur_id or not saving_name or not open_date or not open_amount or not balance or not password:
                messagebox.showerror("错误", "所有字段不能为空！")
                return

            exists = Database.fetch_one("SELECT cardID FROM cardinfo WHERE cardID = %s", (card_id,))
            if exists:
                messagebox.showerror("错误", "该卡号已存在！")
                return

            # 获取对应的 savingID - 修复后的代码
            saving_result = Database.fetch_one("SELECT savingID FROM deposit WHERE savingName = %s", (saving_name,))
            if not saving_result:
                messagebox.showerror("错误", f"不存在名为 '{saving_name}' 的存款业务类型！")
                return
            saving_id = saving_result["savingID"]

            result = Database.execute_query(
                "INSERT INTO cardinfo (cardID, customerID, curID, savingID, openDate, openMoney, balance, pass, IsReportLoss) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)",
                (card_id, customer_id, cur_id, saving_id, open_date, open_amount, balance, password, is_lost)
            )

            if result:
                messagebox.showinfo("成功", "银行卡添加成功！")
                dialog.destroy()
                self.load_bank_cards()
            else:
                messagebox.showerror("错误", "银行卡添加失败！")

        tk.Button(
            dialog, 
            text="保存", 
            command=validate_and_save,
            bg=self.btn_bg,
            fg=self.btn_fg,
            font=self.font,
            padx=10,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).place(relx=0.4, rely=0.95, anchor=tk.CENTER)

        tk.Button(
            dialog, 
            text="取消", 
            command=dialog.destroy,
            bg="#CCCCCC",
            fg="black",
            font=self.font,
            padx=10,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).place(relx=0.6, rely=0.95, anchor=tk.CENTER)

    def handle_report_loss(self):
        """处理银行卡挂失/解挂"""
        card_id = self.get_selected_bank_card()
        if not card_id:
            return

        card = Database.fetch_one("SELECT IsReportLoss FROM cardinfo WHERE cardID = %s", (card_id,))
        if not card:
            messagebox.showerror("错误", "获取银行卡信息失败！")
            return

        # 标准化当前挂失状态
        current_status = str(card["IsReportLoss"]).strip()
        if current_status == '是' or current_status == '1' or current_status.upper() == 'TRUE':
            is_lost = True
        else:
            is_lost = False
        
        # 切换挂失状态
        new_status = "否" if is_lost else "是"

        result = Database.execute_query(
            "UPDATE cardinfo SET IsReportLoss = %s WHERE cardID = %s",
            (new_status, card_id)
        )

        if result:
            messagebox.showinfo("成功", f"银行卡挂失状态已更新为：{'挂失' if new_status == '是' else '正常'}")
            self.load_bank_cards()
        else:
            messagebox.showerror("错误", "更新挂失状态失败！")

    def handle_change_password(self):
        """处理银行卡密码修改"""
        card_id = self.get_selected_bank_card()
        if not card_id:
            return

        card = Database.fetch_one("SELECT pass FROM cardinfo WHERE cardID = %s", (card_id,))
        if not card:
            messagebox.showerror("错误", "获取银行卡信息失败！")
            return

        current_password = card["pass"]

        dialog = tk.Toplevel(self.root)
        dialog.title("修改银行卡密码")
        dialog.geometry("300x200")
        dialog.configure(bg="#E6F7FF")
        dialog.transient(self.root)
        dialog.grab_set()

        tk.Label(dialog, text="当前密码:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.2, anchor=tk.W)
        current_password_var = tk.StringVar(master=dialog, value=current_password)
        tk.Entry(dialog, textvariable=current_password_var, width=20, state="readonly").place(relx=0.5, rely=0.2, anchor=tk.CENTER)

        tk.Label(dialog, text="新密码:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.4, anchor=tk.W)
        new_password_var = tk.StringVar(master=dialog)
        tk.Entry(dialog, textvariable=new_password_var, width=20).place(relx=0.5, rely=0.4, anchor=tk.CENTER)

        tk.Label(dialog, text="确认新密码:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.6, anchor=tk.W)
        confirm_password_var = tk.StringVar(master=dialog)
        tk.Entry(dialog, textvariable=confirm_password_var, width=20).place(relx=0.5, rely=0.6, anchor=tk.CENTER)

        def validate_and_save():
            new_password = new_password_var.get().strip()
            confirm_password = confirm_password_var.get().strip()

            if not new_password or not confirm_password:
                messagebox.showerror("错误", "密码不能为空！")
                return

            if new_password != confirm_password:
                messagebox.showerror("错误", "两次输入的新密码不一致！")
                return

            result = Database.execute_query(
                "UPDATE cardinfo SET pass = %s WHERE cardID = %s",
                (new_password, card_id)
            )

            if result:
                messagebox.showinfo("成功", "银行卡密码修改成功！")
                dialog.destroy()
                self.load_bank_cards()
            else:
                messagebox.showerror("错误", "银行卡密码修改失败！")

        tk.Button(
            dialog, 
            text="保存", 
            command=validate_and_save,
            bg=self.btn_bg,
            fg=self.btn_fg,
            font=self.font,
            padx=10,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).place(relx=0.4, rely=0.8, anchor=tk.CENTER)

        tk.Button(
            dialog, 
            text="取消", 
            command=dialog.destroy,
            bg="#CCCCCC",
            fg="black",
            font=self.font,
            padx=10,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).place(relx=0.6, rely=0.8, anchor=tk.CENTER)

    def modify_bank_card(self):
        """修改银行卡信息"""
        card_id = self.get_selected_bank_card()
        if not card_id:
            return

        card = Database.fetch_one(
            """
            SELECT cardinfo.cardID, cardinfo.customerID, cardinfo.curID, deposit.savingName, 
                   cardinfo.openDate, cardinfo.openMoney AS openAmount, cardinfo.balance, 
                   cardinfo.IsReportLoss AS isLost
            FROM cardinfo
            JOIN deposit ON cardinfo.savingID = deposit.savingID
            WHERE cardinfo.cardID = %s
            """,
            (card_id,)
        )

        if not card:
            messagebox.showerror("错误", "获取银行卡信息失败！")
            return

        dialog = tk.Toplevel(self.root)
        dialog.title("修改银行卡信息")
        dialog.geometry("400x450")
        dialog.configure(bg="#E6F7FF")
        dialog.transient(self.root)
        dialog.grab_set()

        card_id_var = tk.StringVar(value=card["cardID"])
        customer_id_var = tk.StringVar(value=card["customerID"])
        cur_id_var = tk.StringVar(value=card["curID"])
        saving_name_var = tk.StringVar(value=card["savingName"])
        open_date_var = tk.StringVar(value=card["openDate"].strftime("%Y-%m-%d"))
        open_amount_var = tk.StringVar(value=card["openAmount"])
        balance_var = tk.StringVar(value=card["balance"])
        is_lost_var = tk.StringVar(value=card["isLost"])

        tk.Label(dialog, text="卡号:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.1, anchor=tk.W)
        tk.Entry(dialog, textvariable=card_id_var, width=30, state="readonly").place(relx=0.5, rely=0.1, anchor=tk.CENTER)

        tk.Label(dialog, text="客户编号:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.2, anchor=tk.W)
        tk.Entry(dialog, textvariable=customer_id_var, width=30).place(relx=0.5, rely=0.2, anchor=tk.CENTER)

        tk.Label(dialog, text="币种:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.3, anchor=tk.W)
        tk.Entry(dialog, textvariable=cur_id_var, width=30).place(relx=0.5, rely=0.3, anchor=tk.CENTER)

        tk.Label(dialog, text="存款名称:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.4, anchor=tk.W)
        tk.Entry(dialog, textvariable=saving_name_var, width=30).place(relx=0.5, rely=0.4, anchor=tk.CENTER)

        tk.Label(dialog, text="开户日期:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.5, anchor=tk.W)
        tk.Entry(dialog, textvariable=open_date_var, width=30).place(relx=0.5, rely=0.5, anchor=tk.CENTER)

        tk.Label(dialog, text="开户金额:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.6, anchor=tk.W)
        tk.Entry(dialog, textvariable=open_amount_var, width=30).place(relx=0.5, rely=0.6, anchor=tk.CENTER)

        tk.Label(dialog, text="余额:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.7, anchor=tk.W)
        tk.Entry(dialog, textvariable=balance_var, width=30).place(relx=0.5, rely=0.7, anchor=tk.CENTER)

        tk.Label(dialog, text="是否挂失:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.8, anchor=tk.W)
        tk.Entry(dialog, textvariable=is_lost_var, width=30).place(relx=0.5, rely=0.8, anchor=tk.CENTER)

        def validate_and_save():
            customer_id = customer_id_var.get().strip()
            cur_id = cur_id_var.get().strip()
            saving_name = saving_name_var.get().strip()
            open_date = open_date_var.get().strip()
            open_amount = open_amount_var.get().strip()
            balance = balance_var.get().strip()
            is_lost = is_lost_var.get().strip()

            if not customer_id or not cur_id or not saving_name or not open_date or not open_amount or not balance:
                messagebox.showerror("错误", "所有字段不能为空！")
                return

            # 获取对应的 savingID
            saving_id = Database.fetch_one("SELECT savingID FROM deposit WHERE savingName = %s", (saving_name,))["savingID"]

            result = Database.execute_query(
                """
                UPDATE cardinfo
                SET customerID = %s, curID = %s, savingID = %s, openDate = %s, openMoney = %s, balance = %s, IsReportLoss = %s
                WHERE cardID = %s
                """,
                (customer_id, cur_id, saving_id, open_date, open_amount, balance, is_lost, card_id)
            )

            if result:
                messagebox.showinfo("成功", "银行卡信息修改成功！")
                dialog.destroy()
                self.load_bank_cards()
            else:
                messagebox.showerror("错误", "银行卡信息修改失败！")

        tk.Button(
            dialog, 
            text="保存", 
            command=validate_and_save,
            bg=self.btn_bg,
            fg=self.btn_fg,
            font=self.font,
            padx=10,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).place(relx=0.4, rely=0.9, anchor=tk.CENTER)

        tk.Button(
            dialog, 
            text="取消", 
            command=dialog.destroy,
            bg="#CCCCCC",
            fg="black",
            font=self.font,
            padx=10,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).place(relx=0.6, rely=0.9, anchor=tk.CENTER)

    def delete_bank_card(self):
        """删除银行卡"""
        card_id = self.get_selected_bank_card()
        if not card_id:
            return

        if not messagebox.askyesno("确认", "确定要删除该银行卡吗？此操作不可恢复！"):
            return

        result = Database.execute_query("DELETE FROM cardinfo WHERE cardID = %s", (card_id,))

        if result:
            messagebox.showinfo("成功", "银行卡删除成功！")
            self.load_bank_cards()
        else:
            messagebox.showerror("错误", "银行卡删除失败！")

    def export_to_csv(self):
        """导出银行卡数据到 CSV"""
        bank_cards = Database.fetch_all(
            """
            SELECT cardinfo.cardID, cardinfo.customerID, cardinfo.curID, deposit.savingName, 
                   cardinfo.openDate, cardinfo.openMoney AS openAmount, cardinfo.balance, 
                   cardinfo.IsReportLoss AS isLost
            FROM cardinfo
            JOIN deposit ON cardinfo.savingID = deposit.savingID
            """
        )
        if not bank_cards:
            messagebox.showinfo("提示", "没有银行卡数据可导出！")
            return

        file_path = filedialog.asksaveasfilename(
            defaultextension=".csv",
            filetypes=[("CSV文件", "*.csv"), ("所有文件", "*.*")],
            title="保存CSV文件"
        )

        if not file_path:
            return

        try:
            with open(file_path, 'w', newline='', encoding='utf-8-sig') as f:
                writer = csv.writer(f)
                writer.writerow(["卡号", "客户编号", "币种", "存款名称", "开户日期", "开户金额", "余额", "是否挂失"])
                for card in bank_cards:
                    writer.writerow([
                        card["cardID"],
                        card["customerID"],
                        card["curID"],
                        card["savingName"],
                        card["openDate"].strftime("%Y-%m-%d %H:%M:%S"),
                        card["openAmount"],
                        card["balance"],
                        "是" if card["isLost"] == "是" else "否"
                    ])

            messagebox.showinfo("成功", f"银行卡数据已成功导出到\n{file_path}")
        except Exception as e:
            messagebox.showerror("错误", f"导出失败：{str(e)}")

    def get_selected_bank_card(self):
        """获取选中的银行卡ID"""
        selected_items = self.bank_card_tree.selection()
        if not selected_items:
            messagebox.showwarning("警告", "请先选择一张银行卡！")
            return None

        item = self.bank_card_tree.item(selected_items[0])
        return item["values"][0]  # 返回银行卡号

    def show_bank_card_details(self):
        """显示银行卡详情"""
        card_id = self.get_selected_bank_card()
        if not card_id:
            return

        card = Database.fetch_one(
            """
            SELECT cardinfo.cardID, cardinfo.customerID, cardinfo.curID, deposit.savingName, 
                   cardinfo.openDate, cardinfo.openMoney AS openAmount, cardinfo.balance, 
                   cardinfo.pass AS password, cardinfo.IsReportLoss AS isLost
            FROM cardinfo
            JOIN deposit ON cardinfo.savingID = deposit.savingID
            WHERE cardinfo.cardID = %s
            """,
            (card_id,)
        )

        if not card:
            messagebox.showerror("错误", "获取银行卡信息失败！")
            return

        dialog = tk.Toplevel(self.root)
        dialog.title(f"银行卡详情 - {card['cardID']}")
        dialog.geometry("400x300")
        dialog.configure(bg="#E6F7FF")

        tk.Label(dialog, text="卡号:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.1, anchor=tk.W)
        tk.Label(dialog, text=card["cardID"], font=self.font).place(relx=0.5, rely=0.1, anchor=tk.CENTER)

        tk.Label(dialog, text="客户编号:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.2, anchor=tk.W)
        tk.Label(dialog, text=card["customerID"], font=self.font).place(relx=0.5, rely=0.2, anchor=tk.CENTER)

        tk.Label(dialog, text="币种:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.3, anchor=tk.W)
        tk.Label(dialog, text=card["curID"], font=self.font).place(relx=0.5, rely=0.3, anchor=tk.CENTER)

        tk.Label(dialog, text="存款名称:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.4, anchor=tk.W)
        tk.Label(dialog, text=card["savingName"], font=self.font).place(relx=0.5, rely=0.4, anchor=tk.CENTER)

        tk.Label(dialog, text="开户日期:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.5, anchor=tk.W)
        tk.Label(dialog, text=card["openDate"].strftime("%Y-%m-%d %H:%M:%S"), font=self.font).place(relx=0.5, rely=0.5, anchor=tk.CENTER)

        tk.Label(dialog, text="开户金额:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.6, anchor=tk.W)
        tk.Label(dialog, text=card["openAmount"], font=self.font).place(relx=0.5, rely=0.6, anchor=tk.CENTER)

        tk.Label(dialog, text="余额:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.7, anchor=tk.W)
        tk.Label(dialog, text=card["balance"], font=self.font).place(relx=0.5, rely=0.7, anchor=tk.CENTER)

        tk.Label(dialog, text="是否挂失:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.8, anchor=tk.W)
        tk.Label(dialog, text="是" if card["isLost"] == "是" else "否", font=self.font).place(relx=0.5, rely=0.8, anchor=tk.CENTER)

        tk.Button(
            dialog, 
            text="关闭", 
            command=dialog.destroy,
            bg="#CCCCCC",
            fg="black",
            font=self.font,
            padx=10,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).place(relx=0.5, rely=0.9, anchor=tk.CENTER)
        
# ========== 存款业务管理界面 ==========
class DepositManagement:
    def __init__(self, root, username):
        self.root = root
        self.root.title("管理员 - 存款业务管理")
        self.root.geometry("900x600")
        self.root.configure(bg="#E6F7FF")
        self.username = username
        
        # 界面配置
        self.btn_bg = "#66CCFF"
        self.btn_fg = "white"
        self.font = ("SimHei", 10)
        self.title_font = ("SimHei", 12, "bold")
        
        self.create_widgets()
        self.load_deposits()

    def create_widgets(self):
        """创建存款业务管理界面组件"""
        # 标题
        tk.Label(
            self.root, 
            text="存款业务管理系统", 
            font=("SimHei", 16, "bold"),
            bg="#E6F7FF",
            fg="#333333"
        ).pack(pady=10)
        
        # 功能按钮栏
        btn_frame = tk.Frame(self.root, bg="#E6F7FF")
        btn_frame.pack(fill=tk.X, padx=20, pady=10)
        
        tk.Button(
            btn_frame, 
            text="添加存款业务", 
            command=self.add_deposit,
            bg=self.btn_bg,
            fg=self.btn_fg,
            font=self.font,
            padx=10,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).pack(side=tk.LEFT, padx=5)
        
        tk.Button(
            btn_frame, 
            text="修改存款业务", 
            command=self.modify_deposit,
            bg=self.btn_bg,
            fg=self.btn_fg,
            font=self.font,
            padx=10,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).pack(side=tk.LEFT, padx=5)
        
        tk.Button(
            btn_frame, 
            text="删除存款业务", 
            command=self.delete_deposit,
            bg=self.btn_bg,
            fg=self.btn_fg,
            font=self.font,
            padx=10,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).pack(side=tk.LEFT, padx=5)
        
        tk.Button(
            btn_frame, 
            text="导出CSV", 
            command=self.export_to_csv,
            bg=self.btn_bg,
            fg=self.btn_fg,
            font=self.font,
            padx=10,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).pack(side=tk.LEFT, padx=5)
        
        # 搜索栏
        search_frame = tk.Frame(self.root, bg="#E6F7FF")
        search_frame.pack(fill=tk.X, padx=20, pady=5)
        
        tk.Label(
            search_frame, 
            text="搜索存款业务:", 
            font=self.font,
            bg="#E6F7FF",
            fg="#333333"
        ).pack(side=tk.LEFT, padx=5)
        
        self.search_var = tk.StringVar()
        tk.Entry(
            search_frame, 
            textvariable=self.search_var,
            width=30,
            font=self.font,
            bd=1,
            relief="solid"
        ).pack(side=tk.LEFT, padx=5, fill=tk.X, expand=True)
        
        tk.Button(
            search_frame, 
            text="搜索", 
            command=self.search_deposits,
            bg=self.btn_bg,
            fg=self.btn_fg,
            font=self.font,
            padx=5,
            pady=2,
            relief="flat",
            cursor="hand2"
        ).pack(side=tk.LEFT, padx=5)
        
        tk.Button(
            search_frame, 
            text="重置", 
            command=self.load_deposits,
            bg="#CCCCCC",
            fg="black",
            font=self.font,
            padx=5,
            pady=2,
            relief="flat",
            cursor="hand2"
        ).pack(side=tk.LEFT, padx=5)
        
        # 存款业务列表
        self.deposit_tree = ttk.Treeview(
            self.root,
            columns=("savingID", "savingName", "descrip"),
            show="headings",
            height=15
        )
        
        self.deposit_tree.heading("savingID", text="业务类型编号")
        self.deposit_tree.heading("savingName", text="业务名称")
        self.deposit_tree.heading("descrip", text="描述")
        
        self.deposit_tree.column("savingID", width=100, anchor=tk.CENTER)
        self.deposit_tree.column("savingName", width=200, anchor=tk.CENTER)
        self.deposit_tree.column("descrip", width=400, anchor=tk.CENTER)
        
        self.deposit_tree.pack(fill=tk.BOTH, expand=True, padx=20, pady=10)
        self.deposit_tree.bind("<Double-1>", lambda e: self.show_deposit_details())
        
        # 状态栏
        self.status_var = tk.StringVar()
        self.status_var.set(f"当前用户: {self.username} | 存款业务数量: 0")
        tk.Label(
            self.root, 
            textvariable=self.status_var, 
            font=self.font,
            bg="#E6F7FF",
            fg="#333333"
        ).pack(side=tk.BOTTOM, fill=tk.X, padx=20, pady=5)

    def load_deposits(self):
        """加载所有存款业务信息"""
        for item in self.deposit_tree.get_children():
            self.deposit_tree.delete(item)
        
        query = "SELECT savingID, savingName, descrip FROM deposit"
        deposits = Database.fetch_all(query)
        
        if deposits:
            for deposit in deposits:
                self.deposit_tree.insert(
                    "", 
                    tk.END,
                    values=(
                        deposit["savingID"],
                        deposit["savingName"],
                        deposit["descrip"]
                    )
                )
            self.status_var.set(f"当前用户: {self.username} | 存款业务数量: {len(deposits)}")
        else:
            self.status_var.set(f"当前用户: {self.username} | 存款业务数量: 0")

    def search_deposits(self):
        """搜索存款业务信息"""
        keyword = self.search_var.get().strip()
        if not keyword:
            self.load_deposits()
            return
        
        for item in self.deposit_tree.get_children():
            self.deposit_tree.delete(item)
        
        query = """
        SELECT savingID, savingName, descrip
        FROM deposit
        WHERE savingName LIKE %s OR descrip LIKE %s
        """
        deposits = Database.fetch_all(query, (f"%{keyword}%", f"%{keyword}%"))
        
        if deposits:
            for deposit in deposits:
                self.deposit_tree.insert(
                    "", 
                    tk.END,
                    values=(
                        deposit["savingID"],
                        deposit["savingName"],
                        deposit["descrip"]
                    )
                )
            self.status_var.set(f"搜索结果: {len(deposits)} 条")
        else:
            self.status_var.set("搜索结果: 未找到匹配的存款业务")

    def add_deposit(self):
        """添加新存款业务"""
        dialog = tk.Toplevel(self.root)
        dialog.title("添加存款业务")
        dialog.geometry("400x300")
        dialog.configure(bg="#E6F7FF")
        dialog.transient(self.root)
        dialog.grab_set()
        
        saving_name_var = tk.StringVar(master=dialog)
        descrip_var = tk.StringVar(master=dialog)
        
        tk.Label(dialog, text="业务名称:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.2, anchor=tk.W)
        tk.Entry(dialog, textvariable=saving_name_var, width=30).place(relx=0.5, rely=0.2, anchor=tk.CENTER)
        
        tk.Label(dialog, text="描述:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.4, anchor=tk.W)
        tk.Entry(dialog, textvariable=descrip_var, width=30).place(relx=0.5, rely=0.4, anchor=tk.CENTER)
        
        def validate_and_save():
            saving_name = saving_name_var.get().strip()
            descrip = descrip_var.get().strip()
            
            if not saving_name or not descrip:
                messagebox.showerror("错误", "业务名称和描述不能为空！")
                return
            
            result = Database.execute_query(
                "INSERT INTO deposit (savingName, descrip) VALUES (%s, %s)",
                (saving_name, descrip)
            )
            
            if result:
                messagebox.showinfo("成功", "存款业务添加成功！")
                dialog.destroy()
                self.load_deposits()
            else:
                messagebox.showerror("错误", "存款业务添加失败！")
        
        tk.Button(
            dialog, 
            text="保存", 
            command=validate_and_save,
            bg=self.btn_bg,
            fg=self.btn_fg,
            font=self.font,
            padx=10,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).place(relx=0.4, rely=0.7, anchor=tk.CENTER)
        
        tk.Button(
            dialog, 
            text="取消", 
            command=dialog.destroy,
            bg="#CCCCCC",
            fg="black",
            font=self.font,
            padx=10,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).place(relx=0.6, rely=0.7, anchor=tk.CENTER)

    def modify_deposit(self):
        """修改指定的存款业务信息"""
        selected_item = self.deposit_tree.selection()
        if not selected_item:
            messagebox.showwarning("警告", "请先选择一个存款业务！")
            return
        
        item = self.deposit_tree.item(selected_item)
        saving_id = item["values"][0]
        
        deposit = Database.fetch_one("SELECT savingName, descrip FROM deposit WHERE savingID = %s", (saving_id,))
        if not deposit:
            messagebox.showerror("错误", "获取存款业务信息失败！")
            return
        
        dialog = tk.Toplevel(self.root)
        dialog.title("修改存款业务")
        dialog.geometry("400x300")
        dialog.configure(bg="#E6F7FF")
        dialog.transient(self.root)
        dialog.grab_set()
        
        saving_name_var = tk.StringVar(master=dialog, value=deposit["savingName"])
        descrip_var = tk.StringVar(master=dialog, value=deposit["descrip"])
        
        tk.Label(dialog, text="业务名称:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.2, anchor=tk.W)
        tk.Entry(dialog, textvariable=saving_name_var, width=30).place(relx=0.5, rely=0.2, anchor=tk.CENTER)
        
        tk.Label(dialog, text="描述:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.4, anchor=tk.W)
        tk.Entry(dialog, textvariable=descrip_var, width=30).place(relx=0.5, rely=0.4, anchor=tk.CENTER)
        
        def validate_and_save():
            saving_name = saving_name_var.get().strip()
            descrip = descrip_var.get().strip()
            
            if not saving_name or not descrip:
                messagebox.showerror("错误", "业务名称和描述不能为空！")
                return
            
            result = Database.execute_query(
                "UPDATE deposit SET savingName = %s, descrip = %s WHERE savingID = %s",
                (saving_name, descrip, saving_id)
            )
            
            if result:
                messagebox.showinfo("成功", "存款业务信息修改成功！")
                dialog.destroy()
                self.load_deposits()
            else:
                messagebox.showerror("错误", "存款业务信息修改失败！")
        
        tk.Button(
            dialog, 
            text="保存", 
            command=validate_and_save,
            bg=self.btn_bg,
            fg=self.btn_fg,
            font=self.font,
            padx=10,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).place(relx=0.4, rely=0.7, anchor=tk.CENTER)
        
        tk.Button(
            dialog, 
            text="取消", 
            command=dialog.destroy,
            bg="#CCCCCC",
            fg="black",
            font=self.font,
            padx=10,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).place(relx=0.6, rely=0.7, anchor=tk.CENTER)

    def delete_deposit(self):
        """删除指定的存款业务"""
        selected_item = self.deposit_tree.selection()
        if not selected_item:
            messagebox.showwarning("警告", "请先选择一个存款业务！")
            return
        
        item = self.deposit_tree.item(selected_item)
        saving_id = item["values"][0]
        
        if not messagebox.askyesno("确认", "确定要删除该存款业务吗？此操作不可恢复！"):
            return
        
        result = Database.execute_query("DELETE FROM deposit WHERE savingID = %s", (saving_id,))
        
        if result:
            messagebox.showinfo("成功", "存款业务删除成功！")
            self.load_deposits()
        else:
            messagebox.showerror("错误", "存款业务删除失败！")

    def export_to_csv(self):
        """导出存款业务数据到 CSV"""
        deposits = Database.fetch_all("SELECT savingID, savingName, descrip FROM deposit")
        if not deposits:
            messagebox.showinfo("提示", "没有存款业务数据可导出！")
            return
        
        file_path = filedialog.asksaveasfilename(
            defaultextension=".csv",
            filetypes=[("CSV文件", "*.csv"), ("所有文件", "*.*")],
            title="保存CSV文件"
        )
        
        if not file_path:
            return
        
        try:
            with open(file_path, 'w', newline='', encoding='utf-8-sig') as f:
                writer = csv.writer(f)
                writer.writerow(["业务类型编号", "业务名称", "描述"])
                for deposit in deposits:
                    writer.writerow([
                        deposit["savingID"],
                        deposit["savingName"],
                        deposit["descrip"]
                    ])
            
            messagebox.showinfo("成功", f"存款业务数据已成功导出到\n{file_path}")
        except Exception as e:
            messagebox.showerror("错误", f"导出失败：{str(e)}")

    def get_selected_deposit(self):
        """获取选中的存款业务ID"""
        selected_item = self.deposit_tree.selection()
        if not selected_item:
            messagebox.showwarning("警告", "请先选择一个存款业务！")
            return None
        
        item = self.deposit_tree.item(selected_item)
        return item["values"][0]  # 返回业务类型编号

    def show_deposit_details(self):
        """显示存款业务详情"""
        saving_id = self.get_selected_deposit()
        if not saving_id:
            return
        
        deposit = Database.fetch_one("SELECT savingID, savingName, descrip FROM deposit WHERE savingID = %s", (saving_id,))
        if not deposit:
            messagebox.showerror("错误", "获取存款业务信息失败！")
            return
        
        dialog = tk.Toplevel(self.root)
        dialog.title(f"存款业务详情 - {deposit['savingName']}")
        dialog.geometry("400x300")
        dialog.configure(bg="#E6F7FF")
        
        tk.Label(dialog, text="业务类型编号:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.2, anchor=tk.W)
        tk.Label(dialog, text=deposit["savingID"], font=self.font).place(relx=0.5, rely=0.2, anchor=tk.CENTER)
        
        tk.Label(dialog, text="业务名称:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.4, anchor=tk.W)
        tk.Label(dialog, text=deposit["savingName"], font=self.font).place(relx=0.5, rely=0.4, anchor=tk.CENTER)
        
        tk.Label(dialog, text="描述:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.6, anchor=tk.W)
        tk.Label(dialog, text=deposit["descrip"], font=self.font).place(relx=0.5, rely=0.6, anchor=tk.CENTER)
        
        tk.Button(
            dialog, 
            text="关闭", 
            command=dialog.destroy,
            bg="#CCCCCC",
            fg="black",
            font=self.font,
            padx=10,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).place(relx=0.5, rely=0.9, anchor=tk.CENTER)

# ========== 交易管理界面 ==========
class TransactionManagement:
    def __init__(self, root, username):
        self.root = root
        self.root.title("管理员 - 交易管理")
        self.root.geometry("900x600")
        self.root.configure(bg="#E6F7FF")
        self.username = username
        
        # 界面配置
        self.btn_bg = "#66CCFF"
        self.btn_fg = "white"
        self.font = ("SimHei", 10)
        self.title_font = ("SimHei", 12, "bold")
        
        self.create_widgets()
        self.load_transactions()

    def create_widgets(self):
        """创建交易管理界面组件"""
        # 标题
        tk.Label(
            self.root, 
            text="交易管理系统", 
            font=("SimHei", 16, "bold"),
            bg="#E6F7FF",
            fg="#333333"
        ).pack(pady=10)
        
        # 功能按钮栏
        btn_frame = tk.Frame(self.root, bg="#E6F7FF")
        btn_frame.pack(fill=tk.X, padx=20, pady=10)
        
        tk.Button(
            btn_frame, 
            text="添加交易记录", 
            command=self.add_transaction,
            bg=self.btn_bg,
            fg=self.btn_fg,
            font=self.font,
            padx=10,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).pack(side=tk.LEFT, padx=5)
        
        tk.Button(
            btn_frame, 
            text="删除交易记录", 
            command=self.delete_transaction,
            bg=self.btn_bg,
            fg=self.btn_fg,
            font=self.font,
            padx=10,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).pack(side=tk.LEFT, padx=5)
        
        tk.Button(
            btn_frame, 
            text="导出CSV", 
            command=self.export_to_csv,
            bg=self.btn_bg,
            fg=self.btn_fg,
            font=self.font,
            padx=10,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).pack(side=tk.LEFT, padx=5)
        
        # 搜索栏
        search_frame = tk.Frame(self.root, bg="#E6F7FF")
        search_frame.pack(fill=tk.X, padx=20, pady=5)
        
        tk.Label(
            search_frame, 
            text="搜索交易:", 
            font=self.font,
            bg="#E6F7FF",
            fg="#333333"
        ).pack(side=tk.LEFT, padx=5)
        
        self.search_var = tk.StringVar()
        tk.Entry(
            search_frame, 
            textvariable=self.search_var,
            width=30,
            font=self.font,
            bd=1,
            relief="solid"
        ).pack(side=tk.LEFT, padx=5, fill=tk.X, expand=True)
        
        tk.Button(
            search_frame, 
            text="搜索", 
            command=self.search_transactions,
            bg=self.btn_bg,
            fg=self.btn_fg,
            font=self.font,
            padx=5,
            pady=2,
            relief="flat",
            cursor="hand2"
        ).pack(side=tk.LEFT, padx=5)
        
        tk.Button(
            search_frame, 
            text="重置", 
            command=self.load_transactions,
            bg="#CCCCCC",
            fg="black",
            font=self.font,
            padx=5,
            pady=2,
            relief="flat",
            cursor="hand2"
        ).pack(side=tk.LEFT, padx=5)
        
        # 交易记录列表
        self.transaction_tree = ttk.Treeview(
            self.root,
            columns=("tradeID", "tradeDate", "tradeType", "tradeMoney", "cardID", "remark"),
            show="headings",
            height=15
        )
        
        self.transaction_tree.heading("tradeID", text="交易编号")
        self.transaction_tree.heading("tradeDate", text="交易时间")
        self.transaction_tree.heading("tradeType", text="交易类型")
        self.transaction_tree.heading("tradeMoney", text="交易金额")
        self.transaction_tree.heading("cardID", text="卡号")
        self.transaction_tree.heading("remark", text="备注")
        
        self.transaction_tree.column("tradeID", width=80, anchor=tk.CENTER)
        self.transaction_tree.column("tradeDate", width=150, anchor=tk.CENTER)
        self.transaction_tree.column("tradeType", width=100, anchor=tk.CENTER)
        self.transaction_tree.column("tradeMoney", width=100, anchor=tk.CENTER)
        self.transaction_tree.column("cardID", width=150, anchor=tk.CENTER)
        self.transaction_tree.column("remark", width=200, anchor=tk.CENTER)
        
        self.transaction_tree.pack(fill=tk.BOTH, expand=True, padx=20, pady=10)
        self.transaction_tree.bind("<Double-1>", lambda e: self.show_transaction_details())
        
        # 状态栏
        self.status_var = tk.StringVar()
        self.status_var.set(f"当前用户: {self.username} | 交易记录数量: 0")
        tk.Label(
            self.root, 
            textvariable=self.status_var, 
            font=self.font,
            bg="#E6F7FF",
            fg="#333333"
        ).pack(side=tk.BOTTOM, fill=tk.X, padx=20, pady=5)

    def load_transactions(self):
        """加载所有交易记录"""
        for item in self.transaction_tree.get_children():
            self.transaction_tree.delete(item)
        
        query = """
        SELECT tradeID, tradeDate, tradeType, tradeMoney, cardID, remark
        FROM tradeinfo
        """
        transactions = Database.fetch_all(query)
        
        if transactions:
            for transaction in transactions:
                self.transaction_tree.insert(
                    "", 
                    tk.END,
                    values=(
                        transaction["tradeID"],
                        transaction["tradeDate"].strftime("%Y-%m-%d %H:%M:%S"),
                        transaction["tradeType"],
                        transaction["tradeMoney"],
                        transaction["cardID"],
                        transaction["remark"] or "无"
                    )
                )
            self.status_var.set(f"当前用户: {self.username} | 交易记录数量: {len(transactions)}")
        else:
            self.status_var.set(f"当前用户: {self.username} | 交易记录数量: 0")

    def search_transactions(self):
        """搜索交易记录"""
        keyword = self.search_var.get().strip()
        if not keyword:
            self.load_transactions()
            return
        
        for item in self.transaction_tree.get_children():
            self.transaction_tree.delete(item)
        
        query = """
        SELECT tradeID, tradeDate, tradeType, tradeMoney, cardID, remark
        FROM tradeinfo
        WHERE tradeType LIKE %s OR cardID LIKE %s OR remark LIKE %s
        """
        transactions = Database.fetch_all(query, (f"%{keyword}%", f"%{keyword}%", f"%{keyword}%"))
        
        if transactions:
            for transaction in transactions:
                self.transaction_tree.insert(
                    "", 
                    tk.END,
                    values=(
                        transaction["tradeID"],
                        transaction["tradeDate"].strftime("%Y-%m-%d %H:%M:%S"),
                        transaction["tradeType"],
                        transaction["tradeMoney"],
                        transaction["cardID"],
                        transaction["remark"] or "无"
                    )
                )
            self.status_var.set(f"搜索结果: {len(transactions)} 条")
        else:
            self.status_var.set("搜索结果: 未找到匹配的交易记录")

    def add_transaction(self):
        """添加新交易记录"""
        dialog = tk.Toplevel(self.root)
        dialog.title("添加交易记录")
        dialog.geometry("400x350")
        dialog.configure(bg="#E6F7FF")
        dialog.transient(self.root)
        dialog.grab_set()
        
        trade_id_var = tk.StringVar(master=dialog)
        trade_type_var = tk.StringVar(master=dialog)
        trade_money_var = tk.StringVar(master=dialog)
        card_id_var = tk.StringVar(master=dialog)
        remark_var = tk.StringVar(master=dialog)
        
        tk.Label(dialog, text="交易编号:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.1, anchor=tk.W)
        tk.Entry(dialog, textvariable=trade_id_var, width=30).place(relx=0.5, rely=0.1, anchor=tk.CENTER)
        
        tk.Label(dialog, text="交易类型:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.2, anchor=tk.W)
        tk.Entry(dialog, textvariable=trade_type_var, width=30).place(relx=0.5, rely=0.2, anchor=tk.CENTER)
        
        tk.Label(dialog, text="交易金额:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.3, anchor=tk.W)
        tk.Entry(dialog, textvariable=trade_money_var, width=30).place(relx=0.5, rely=0.3, anchor=tk.CENTER)
        
        tk.Label(dialog, text="卡号:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.4, anchor=tk.W)
        tk.Entry(dialog, textvariable=card_id_var, width=30).place(relx=0.5, rely=0.4, anchor=tk.CENTER)
        
        tk.Label(dialog, text="备注:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.5, anchor=tk.W)
        tk.Entry(dialog, textvariable=remark_var, width=30).place(relx=0.5, rely=0.5, anchor=tk.CENTER)
        
        def validate_and_save():
            trade_id = trade_id_var.get().strip()
            trade_type = trade_type_var.get().strip()
            trade_money = trade_money_var.get().strip()
            card_id = card_id_var.get().strip()
            remark = remark_var.get().strip()
            
            if not trade_id or not trade_type or not trade_money or not card_id:
                messagebox.showerror("错误", "交易编号、类型、金额和卡号不能为空！")
                return
            
            if trade_type not in ["存入", "支取"]:
                messagebox.showerror("错误", "交易类型必须是'存入'或'支取'！")
                return
            
            try:
                trade_money = float(trade_money)
                if trade_money <= 0:
                    raise ValueError
            except ValueError:
                messagebox.showerror("错误", "请输入有效的交易金额！")
                return
            
            if len(card_id) != 16 or not card_id.isdigit():
                messagebox.showerror("错误", "卡号必须是16位数字！")
                return
            
            exists = Database.fetch_one("SELECT tradeID FROM tradeinfo WHERE tradeID = %s", (trade_id,))
            if exists:
                messagebox.showerror("错误", "该交易编号已存在！")
                return
            
            result = Database.execute_query(
                "INSERT INTO tradeinfo (tradeID, tradeType, cardID, tradeMoney, remark) VALUES (%s, %s, %s, %s, %s)",
                (trade_id, trade_type, card_id, trade_money, remark)
            )
            
            if result:
                messagebox.showinfo("成功", "交易记录添加成功！")
                dialog.destroy()
                self.load_transactions()
            else:
                messagebox.showerror("错误", "交易记录添加失败！")
        
        tk.Button(
            dialog, 
            text="保存", 
            command=validate_and_save,
            bg=self.btn_bg,
            fg=self.btn_fg,
            font=self.font,
            padx=10,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).place(relx=0.4, rely=0.7, anchor=tk.CENTER)
        
        tk.Button(
            dialog, 
            text="取消", 
            command=dialog.destroy,
            bg="#CCCCCC",
            fg="black",
            font=self.font,
            padx=10,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).place(relx=0.6, rely=0.7, anchor=tk.CENTER)

    def delete_transaction(self):
        """删除指定的交易记录"""
        selected_item = self.transaction_tree.selection()
        if not selected_item:
            messagebox.showwarning("警告", "请先选择一个交易记录！")
            return
        
        item = self.transaction_tree.item(selected_item)
        trade_id = item["values"][0]
        
        if not messagebox.askyesno("确认", "确定要删除该交易记录吗？此操作不可恢复！"):
            return
        
        result = Database.execute_query("DELETE FROM tradeinfo WHERE tradeID = %s", (trade_id,))
        
        if result:
            messagebox.showinfo("成功", "交易记录删除成功！")
            self.load_transactions()
        else:
            messagebox.showerror("错误", "交易记录删除失败！")

    def export_to_csv(self):
        """导出交易数据到 CSV"""
        transactions = Database.fetch_all(
            """
            SELECT tradeID, tradeDate, tradeType, tradeMoney, cardID, remark
            FROM tradeinfo
            """
        )
        if not transactions:
            messagebox.showinfo("提示", "没有交易数据可导出！")
            return
        
        file_path = filedialog.asksaveasfilename(
            defaultextension=".csv",
            filetypes=[("CSV文件", "*.csv"), ("所有文件", "*.*")],
            title="保存CSV文件"
        )
        
        if not file_path:
            return
        
        try:
            with open(file_path, 'w', newline='', encoding='utf-8-sig') as f:
                writer = csv.writer(f)
                writer.writerow(["交易编号", "交易时间", "交易类型", "交易金额", "卡号", "备注"])
                for transaction in transactions:
                    writer.writerow([
                        transaction["tradeID"],
                        transaction["tradeDate"].strftime("%Y-%m-%d %H:%M:%S"),
                        transaction["tradeType"],
                        transaction["tradeMoney"],
                        transaction["cardID"],
                        transaction["remark"] or "无"
                    ])
            
            messagebox.showinfo("成功", f"交易数据已成功导出到\n{file_path}")
        except Exception as e:
            messagebox.showerror("错误", f"导出失败：{str(e)}")

    def get_selected_transaction(self):
        """获取选中的交易记录ID"""
        selected_item = self.transaction_tree.selection()
        if not selected_item:
            messagebox.showwarning("警告", "请先选择一个交易记录！")
            return None
        
        item = self.transaction_tree.item(selected_item)
        return item["values"][0]  # 返回交易记录编号

    def show_transaction_details(self):
        """显示交易记录详情"""
        trade_id = self.get_selected_transaction()
        if not trade_id:
            return
        
        transaction = Database.fetch_one(
            """
            SELECT tradeID, tradeDate, tradeType, tradeMoney, cardID, remark
            FROM tradeinfo
            WHERE tradeID = %s
            """,
            (trade_id,)
        )
        
        if not transaction:
            messagebox.showerror("错误", "获取交易记录失败！")
            return
        
        dialog = tk.Toplevel(self.root)
        dialog.title(f"交易详情 - {transaction['tradeID']}")
        dialog.geometry("400x300")
        dialog.configure(bg="#E6F7FF")
        
        tk.Label(dialog, text="交易编号:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.1, anchor=tk.W)
        tk.Label(dialog, text=transaction["tradeID"], font=self.font).place(relx=0.5, rely=0.1, anchor=tk.CENTER)
        
        tk.Label(dialog, text="交易时间:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.2, anchor=tk.W)
        tk.Label(dialog, text=transaction["tradeDate"].strftime("%Y-%m-%d %H:%M:%S"), font=self.font).place(relx=0.5, rely=0.2, anchor=tk.CENTER)
        
        tk.Label(dialog, text="交易类型:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.3, anchor=tk.W)
        tk.Label(dialog, text=transaction["tradeType"], font=self.font).place(relx=0.5, rely=0.3, anchor=tk.CENTER)
        
        tk.Label(dialog, text="交易金额:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.4, anchor=tk.W)
        tk.Label(dialog, text=transaction["tradeMoney"], font=self.font).place(relx=0.5, rely=0.4, anchor=tk.CENTER)
        
        tk.Label(dialog, text="卡号:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.5, anchor=tk.W)
        tk.Label(dialog, text=transaction["cardID"], font=self.font).place(relx=0.5, rely=0.5, anchor=tk.CENTER)
        
        tk.Label(dialog, text="备注:", font=self.font, bg="#E6F7FF", fg="#333333").place(relx=0.1, rely=0.6, anchor=tk.W)
        tk.Label(dialog, text=transaction["remark"] or "无", font=self.font).place(relx=0.5, rely=0.6, anchor=tk.CENTER)
        
        tk.Button(
            dialog, 
            text="关闭", 
            command=dialog.destroy,
            bg="#CCCCCC",
            fg="black",
            font=self.font,
            padx=10,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).place(relx=0.5, rely=0.9, anchor=tk.CENTER)

# ========== 角色选择界面 ==========
class RoleSelector:
    def __init__(self, root, username):
        self.root = root
        self.root.title("角色选择")
        self.root.geometry("500x500")  
        self.root.resizable(False, False)
        self.username = username
        
        # 界面色彩配置
        self.root.configure(bg="#E6F7FF") 
        self.btn_bg = "#66CCFF"
        self.btn_fg = "white"
        self.font = ("SimHei", 12)
        
        self.create_widgets()  

    def create_widgets(self):
        """创建角色选择界面组件并美化"""
        # 标题，使用place方法居中
        title_label = tk.Label(
            self.root, 
            text=f"欢迎，{self.username}！请选择角色", 
            font=("SimHei", 14, "bold"),
            bg="#E6F7FF",
            fg="#333333"
        )
        title_label.place(relx=0.5, rely=0.2, anchor=tk.CENTER)  

        # 按钮容器，使用place方法居中
        btn_frame = tk.Frame(self.root, bg="#E6F7FF")
        btn_frame.place(relx=0.5, rely=0.5, anchor=tk.CENTER)

        # 普通用户按钮
        tk.Button(
            btn_frame, 
            text="普通用户", 
            command=self.open_normal_user,
            bg=self.btn_bg,
            fg=self.btn_fg,
            font=self.font,
            padx=15,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).grid(row=0, column=0, padx=10)

        # 管理员按钮
        tk.Button(
            btn_frame, 
            text="管理员", 
            command=self.verify_admin,
            bg=self.btn_bg,
            fg=self.btn_fg,
            font=self.font,
            padx=15,
            pady=5,
            relief="flat",
            cursor="hand2"
        ).grid(row=0, column=1, padx=10)

    def verify_admin(self):
        """管理员密码验证"""
        global pwd_root  
        pwd_root = tk.Toplevel(self.root)
        pwd_root.title("管理员验证")
        pwd_root.geometry("300x300")
        pwd_root.resizable(False, False)
        pwd_root.configure(bg="#E6F7FF")
        pwd_root.transient(self.root)  
        pwd_root.grab_set()  

        tk.Label(pwd_root, text="请输入管理员密码：", font=self.font, bg="#E6F7FF", fg="#333333").pack(pady=10)
        pwd_entry = tk.Entry(pwd_root, show="*", font=self.font, bd=1, relief="solid", highlightcolor=self.btn_bg, highlightthickness=1)
        pwd_entry.pack(pady=5)

        def check_pwd():
            pwd = pwd_entry.get()
            if pwd == "88888888":  
                pwd_root.destroy()  
                self.open_admin()
            else:
                messagebox.showerror("错误", "密码不正确！")
                pwd_root.destroy()  

        tk.Button(pwd_root, text="确定", command=check_pwd, bg=self.btn_bg, fg=self.btn_fg, font=self.font, padx=5, pady=2, relief="flat", cursor="hand2").pack(pady=5)

    def open_normal_user(self):
        """进入普通用户界面"""
        self.root.withdraw()  # 隐藏当前窗口
        self.open_user_interface("普通用户")

    def open_admin(self):
        """进入管理员界面"""
        self.root.withdraw()  # 隐藏当前窗口
        self.open_user_interface("管理员")

    def open_user_interface(self, role):
        """根据角色生成对应功能界面"""
        # 创建新窗口
        new_root = tk.Toplevel()
        new_root.title(f"{role}界面")
        new_root.geometry("700x500" if role == "管理员" else "650x550")
        new_root.configure(bg="#E6F7FF")
        
        # 显示角色标题
        role_label = tk.Label(
            new_root, 
            text=f"您当前角色：{role}", 
            font=("SimHei", 14, "bold"),
            bg="#E6F7FF",
            fg="#333333"
        )
        role_label.place(relx=0.5, rely=0.1, anchor=tk.CENTER)  
        
        # 功能按钮区域
        func_frame = tk.Frame(new_root, bg="#E6F7FF")
        func_frame.place(relx=0.5, rely=0.5, anchor=tk.CENTER)
        
        # 功能列表配置
        if role == "普通用户":
            functions = [
                "开户", "存款取款", "转账", 
                "统计分析", "余额查询", "销户",
                "挂失", "修改密码"
            ]
            cols = 3  
        else:  # 管理员
            functions = [
                "客户管理", "银行卡管理", "存款业务管理", 
                "交易管理"
            ]
            cols = 2  
        
        # 计算网格行列数
        rows = (len(functions) + cols - 1) // cols
        
        # 创建功能按钮
        for i, func in enumerate(functions):
            row = i // cols
            col = i % cols
            
            tk.Button(
                func_frame, 
                text=func, 
                command=lambda f=func, r=role, w=new_root: self.show_function(f, r, w),
                bg=self.btn_bg,
                fg=self.btn_fg,
                font=self.font,
                padx=15,
                pady=5,
                relief="flat",
                cursor="hand2",
                width=12  
            ).grid(row=row, column=col, padx=15, pady=15)
        
        # 当用户关闭功能窗口时，显示角色选择窗口
        new_root.protocol("WM_DELETE_WINDOW", lambda: self.on_function_window_close(new_root))

    def on_function_window_close(self, window):
        """当功能窗口关闭时，显示角色选择窗口"""
        window.destroy()
        self.root.deiconify()

    def show_function(self, func_name, role, parent_window):
        """显示功能选择提示或跳转到对应功能"""
        if role == "管理员" and func_name == "客户管理":
        # 打开客户管理界面
           customer_window = tk.Toplevel(parent_window)
           customer_window.title("客户管理系统")
           customer_window.geometry("900x600")
        
        # 创建客户管理界面
           CustomerManagement(customer_window, self.username)
        
        # 当客户管理窗口关闭时，显示管理员界面
           customer_window.protocol("WM_DELETE_WINDOW", lambda: customer_window.destroy())
        elif role == "管理员" and func_name == "银行卡管理":
        # 打开银行卡管理界面
           bank_card_window = tk.Toplevel(parent_window)
           bank_card_window.title("银行卡管理系统")
           bank_card_window.geometry("900x600")
        
        # 创建银行卡管理界面
           BankCardManagement(bank_card_window, self.username)
        
        # 当银行卡管理窗口关闭时，显示管理员界面
           bank_card_window.protocol("WM_DELETE_WINDOW", lambda: bank_card_window.destroy())
        elif role == "管理员" and func_name == "存款业务管理":
        # 打开存款业务管理界面
           deposit_window = tk.Toplevel(parent_window)
           deposit_window.title("存款业务管理系统")
           deposit_window.geometry("900x600")
        
        # 创建存款业务管理界面
           DepositManagement(deposit_window, self.username)
        
        # 当存款业务管理窗口关闭时，显示管理员界面
           deposit_window.protocol("WM_DELETE_WINDOW", lambda: deposit_window.destroy())
        elif role == "管理员" and func_name == "交易管理":
        # 打开交易管理界面
           transaction_window = tk.Toplevel(parent_window)
           transaction_window.title("交易管理系统")
           transaction_window.geometry("900x600")
        
        # 创建交易管理界面
           TransactionManagement(transaction_window, self.username)
        
        # 当交易管理窗口关闭时，显示管理员界面
           transaction_window.protocol("WM_DELETE_WINDOW", lambda: transaction_window.destroy())
        else:
           messagebox.showinfo("功能提示", f"您已选择【{func_name}】功能\n（该功能暂未实现，后续可扩展）")
            
# ========== 登录注册界面 ==========
class AuthApp:
    def __init__(self, root):
        self.root = root
        self.root.title("登录注册系统")
        self.root.geometry("500x500")
        self.root.resizable(False, False)
        
        # 界面色彩配置
        self.root.configure(bg="#F5F8FA")
        self.frame_bg = "#FFFFFF"
        self.label_fg = "#333333"
        self.btn_bg = "#66CCFF"
        self.btn_fg = "white"
        self.font = ("SimHei", 10)
        
        self.main_frame = tk.Frame(root, bg=self.frame_bg)
        self.main_frame.pack(fill=tk.BOTH, expand=True)
        
        self.show_login()

    def create_db_connection(self):
        """安全创建数据库连接"""
        try:
            return pymysql.connect(
                host=DB_CONFIG['host'],
                user=DB_CONFIG['user'],
                password=DB_CONFIG['password'],
                database=DB_CONFIG['database'],
                port=DB_CONFIG['port'],
                cursorclass=pymysql.cursors.DictCursor
            )
        except pymysql.Error as e:
            messagebox.showerror("数据库错误", f"连接失败：{str(e)}")
            return None

    def show_login(self):
        """渲染登录界面"""
        for widget in self.main_frame.winfo_children():
            widget.destroy()
        
        # 标题
        title_label = tk.Label(
            self.main_frame, 
            text="用户登录", 
            font=("SimHei", 16, "bold"),
            bg=self.frame_bg,
            fg=self.label_fg
        )
        title_label.place(relx=0.5, rely=0.2, anchor=tk.CENTER)

        # 用户名输入区域
        username_frame = tk.Frame(self.main_frame, bg=self.frame_bg)
        username_frame.place(relx=0.5, rely=0.35, anchor=tk.CENTER)
        tk.Label(
            username_frame, 
            text="用户名:", 
            font=self.font,
            bg=self.frame_bg,
            fg=self.label_fg
        ).pack(side=tk.LEFT, padx=10)
        self.login_username = tk.Entry(
            username_frame, 
            width=25,
            font=self.font,
            bd=1,
            relief="solid",
            highlightcolor=self.btn_bg,
            highlightthickness=1
        )
        self.login_username.pack(side=tk.LEFT, padx=10, fill=tk.X, expand=True)

        # 身份证号输入区域
        pid_frame = tk.Frame(self.main_frame, bg=self.frame_bg)
        pid_frame.place(relx=0.5, rely=0.45, anchor=tk.CENTER)
        tk.Label(
            pid_frame, 
            text="身份证号:", 
            font=self.font,
            bg=self.frame_bg,
            fg=self.label_fg
        ).pack(side=tk.LEFT, padx=10)
        self.login_pid = tk.Entry(
            pid_frame, 
            width=25,
            font=self.font,
            bd=1,
            relief="solid",
            highlightcolor=self.btn_bg,
            highlightthickness=1
        )
        self.login_pid.pack(side=tk.LEFT, padx=10, fill=tk.X, expand=True)

        # 登录按钮
        login_btn = tk.Button(
            self.main_frame, 
            text="登录", 
            command=self.handle_login,
            bg=self.btn_bg,
            fg=self.btn_fg,
            font=("SimHei", 12, "bold"),
            padx=15,
            pady=5,
            relief="flat",
            cursor="hand2"
        )
        login_btn.place(relx=0.5, rely=0.6, anchor=tk.CENTER)

        # 注册跳转标签
        register_label = tk.Label(
            self.main_frame, 
            text="还没账号？点击注册", 
            fg="#66CCFF", 
            cursor="hand2",
            bg=self.frame_bg,
            font=self.font
        )
        register_label.place(relx=0.5, rely=0.7, anchor=tk.CENTER)
        register_label.bind("<Button-1>", lambda e: self.show_register())

    def render_input(self, label_text, parent, var_name):
        """通用输入框渲染"""
        frame = tk.Frame(parent, bg=self.frame_bg)
        frame.pack(fill=tk.X, pady=10)

        tk.Label(
            frame, 
            text=label_text, 
            font=self.font,
            bg=self.frame_bg,
            fg=self.label_fg
        ).pack(side=tk.LEFT, padx=10)

        entry = tk.Entry(
            frame, 
            width=25,
            font=self.font,
            bd=1,
            relief="solid",
            highlightcolor=self.btn_bg,
            highlightthickness=1
        )
        entry.pack(side=tk.LEFT, padx=10, fill=tk.X, expand=True)
        
        setattr(self, var_name, entry)

    def show_register(self):
        """渲染注册界面"""
        for widget in self.main_frame.winfo_children():
            widget.destroy()
        
        # 标题
        title_label = tk.Label(
            self.main_frame, 
            text="用户注册", 
            font=("SimHei", 16, "bold"),
            bg=self.frame_bg,
            fg=self.label_fg
        )
        title_label.place(relx=0.5, rely=0.2, anchor=tk.CENTER)

        # 用户名输入区域
        username_frame = tk.Frame(self.main_frame, bg=self.frame_bg)
        username_frame.place(relx=0.5, rely=0.35, anchor=tk.CENTER)
        self.render_input("用户名:", username_frame, "reg_username")

        # 身份证号输入区域
        pid_frame = tk.Frame(self.main_frame, bg=self.frame_bg)
        pid_frame.place(relx=0.5, rely=0.45, anchor=tk.CENTER)
        self.render_input("身份证号:", pid_frame, "reg_pid")

        # 联系电话输入区域
        tel_frame = tk.Frame(self.main_frame, bg=self.frame_bg)
        tel_frame.place(relx=0.5, rely=0.55, anchor=tk.CENTER)
        self.render_input("联系电话:", tel_frame, "reg_tel")

        # 注册按钮
        register_btn = tk.Button(
            self.main_frame, 
            text="注册", 
            command=self.handle_register,
            bg=self.btn_bg,
            fg=self.btn_fg,
            font=("SimHei", 12, "bold"),
            padx=15,
            pady=5,
            relief="flat",
            cursor="hand2"
        )
        register_btn.place(relx=0.5, rely=0.65, anchor=tk.CENTER)

        # 登录跳转标签
        login_label = tk.Label(
            self.main_frame, 
            text="已有账号？点击登录", 
            fg="#66CCFF", 
            cursor="hand2",
            bg=self.frame_bg,
            font=self.font
        )
        login_label.place(relx=0.5, rely=0.75, anchor=tk.CENTER)
        login_label.bind("<Button-1>", lambda e: self.show_login())

    def handle_login(self):
        """登录校验逻辑"""
        username = self.login_username.get().strip()
        pid = self.login_pid.get().strip()
        
        if not username or not pid:
            messagebox.showerror("错误", "用户名/身份证号不能为空！")
            return
        
        conn = self.create_db_connection()
        if not conn:
            return
        
        try:
            with conn.cursor() as cursor:
                query = "SELECT customerName FROM userinfo WHERE customerName = %s AND PID = %s"
                cursor.execute(query, (username, pid))
                result = cursor.fetchone()
                
                if result:
                    messagebox.showinfo("成功", "登录成功！")
                    self.root.destroy()  
                    role_root = tk.Tk()
                    RoleSelector(role_root, username)
                    role_root.mainloop()
                else:
                    messagebox.showerror("错误", "用户名或身份证号错误！")
                    
        except pymysql.Error as e:
            messagebox.showerror("数据库错误", f"查询失败：{str(e)}")
        finally:
            if conn and conn.open:
                conn.close()

    def handle_register(self):
        """注册逻辑"""
        username = self.reg_username.get().strip()
        pid = self.reg_pid.get().strip()
        tel = self.reg_tel.get().strip()
        
        if not username or not pid or not tel:
            messagebox.showerror("错误", "信息不能为空！")
            return
        
        if len(pid) not in (15, 18):
            messagebox.showerror("错误", "身份证号应为15或18位！")
            return
        
        conn = self.create_db_connection()
        if not conn:
            return
        
        try:
            with conn.cursor() as cursor:
                cursor.execute("SELECT PID FROM userinfo WHERE PID = %s", (pid,))
                if cursor.fetchone():
                    messagebox.showerror("错误", "该身份证号已注册！")
                    return
                query = "INSERT INTO userinfo (customerName, PID, telephone) VALUES (%s, %s, %s)"
                cursor.execute(query, (username, pid, tel))
                conn.commit()
                messagebox.showinfo("成功", "注册成功！请登录")
                self.show_login()
        except pymysql.Error as e:
            messagebox.showerror("数据库错误", f"注册失败：{str(e)}")
            conn.rollback()
        finally:
            if conn and conn.open:
                conn.close()

# ========== 主程序入口 ==========
if __name__ == "__main__":
    root = tk.Tk()
    app = AuthApp(root)
    root.mainloop()

